import java.util.Arrays;

//底层用数组实现的一个线性表
public class ArrayList<E> {
    //属性内容
    private static int DEFAULT_CAPACITY = 10;   //默认容量
    private E[] data;   //元素的容器
    private int size;   //元素的个数 data.length容量

    //构造函数 创建对象时 对对象属性进行初始化的
    public ArrayList() {
        data = (E[]) new Object[DEFAULT_CAPACITY];
        size = 0;
    }

    //行为内容
    //默认在表尾添加元素element
    public void add(E element) {
        add(size, element);
    }

    //在指定index角标处，添加元素element
    public void add(int index, E element) {
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("角标越界!");
        }
        if (size == data.length) {
            resize(data.length * 2);
        }
        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }
        data[index] = element;
        size++;
    }

    //扩容
    private void resize(int newLength) {
        E[] newData = (E[]) new Object[newLength];
        for (int i = 0; i < size; i++) {
            newData[i] = data[i];
        }
        data = newData;
    }

    //删除指定角标index处的元素，并返回
    public E remove(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("角标越界!");
        }
        E ret = data[index];
        for (int i = index + 1; i < size; i++) {
            data[i - 1] = data[i];
        }
        size--;
        if (size == data.length / 4 && data.length > DEFAULT_CAPACITY) {
            resize(data.length / 2);
        }
        return ret;
    }

    //查找
    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("角标越界!");
        }
        return data[index];
    }

    //修改
    public E set(int index, E element) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("角标越界!");
        }
        E ret = data[index];
        data[index] = element;
        return ret;
    }

    //从左到右第一次出现的位置
    public int indexOf(E element) {
        for (int i = 0; i < size; i++) {
            if (element.equals(data[i])) {
                return i;
            }
        }
        return -1;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public int size() {
        return size;
    }

    @Override
    public String toString() {
        // 1 2 3 4 null null null null
        // "[1, 2, 3, 4]"  "[]"
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isEmpty()) {
            sb.append(']');
        } else {
            for (int i = 0; i < size; i++) {
                sb.append(data[i]);
                if (i != size - 1) {
                    sb.append(',');
                    sb.append(' ');
                } else {
                    sb.append(']');
                }
            }
        }
        return sb.toString();
    }
}